package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.module.common.utility.Constant;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.CsGameDating.CSGameDatingDatingResponse;
import com.motu.monstercity.protocol.CsGameSystem;
import com.motu.monstercity.protocol.CsGameSystem.CSGameSystemRedPointResponse;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.bag.ItemId;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.partner.PartnerConstant;
import com.motu.monstercity.server.game.commondata.secretary.SecretaryMain;
import com.motu.monstercity.server.game.commondata.skill.SkillConstant;
import com.motu.monstercity.server.game.commondata.system.SystemConstant;
import com.motu.monstercity.server.game.commondata.system.UserExp;
import com.motu.monstercity.server.game.log.LogType;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.json.JsonArray;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class DatingManager extends DatingUserData {

    public static final int DATING_DATING_TYPE_OUT_DOOR = 1;// 踏青
    public static final int DATING_DATING_TYPE_DINNER = 2;// 烛光晚餐
    public static final int DATING_DATING_TYPE_FREE = 3;// 免费约会

    // 初始化 下发背包模块的用户数据
    public static void loadInitDatingUserData(PBUserData.Builder pbUserData, UserInfo userInfo) {
        long userId = userInfo.getId();
        UserDating userDating = getUserDating(userId);
        ProtoDataUtils.updatePBUserData(pbUserData, userDating);
    }


    /**
     * 踏青获取消耗品（根据秘书约会次数，消耗量不同）
     *
     * @param userDatingSecretary
     * @param rewardItems
     */
    public static void takeNeedItemNum(UserDatingSecretary userDatingSecretary, List<RewardItem> rewardItems) {
        int len = AllParam.DATING_DATING_DIAMOND_NUM.length;
        long cost;
        if (userDatingSecretary.getDatingCount() >= len) {
            cost = AllParam.DATING_DATING_DIAMOND_NUM[len - 1];
        } else {
            cost = AllParam.DATING_DATING_DIAMOND_NUM[userDatingSecretary.getDatingCount()];
        }
        CommonUtils.addRewardItem(rewardItems, ItemId.DIAMOND, cost);
    }

    /**
     * 烛光晚餐获取消耗道具
     *
     * @param rewardItems
     */
    public static void takeNeedItemNum(List<RewardItem> rewardItems) {
        CommonUtils.addRewardItem(rewardItems, ItemId.DATING_DINNER, 1);
    }

    /**
     * 计算约会基础奖励
     *
     * @param userSecretary
     * @param type
     */
    public static RewardItem takeRewardItemNum(long userId, UserSecretary userSecretary, int type) {
        int baseValue = userSecretary.getCharm();// 基本奖励数量
        SecretaryMain secretaryMain = SecretaryManager.getSecretaryMain(userSecretary.getSecretaryId());
        // 技能加成 与性格开朗的秘书约会羁绊值提升@
        int totalAdd = SkillManager.getSkillMoudleAdd(userId, SkillConstant.EFFECT_TYPE_23, secretaryMain.getDisposition());
        switch (type) {
            case DATING_DATING_TYPE_OUT_DOOR: // 踏青
                totalAdd += AllParam.DATING_DATING_TYPE_DIAMOND_PRE;
                break;
            case DATING_DATING_TYPE_DINNER: // 烛光晚餐
                totalAdd += AllParam.DATING_DATING_TYPE_DINNER_PRE;
                break;
        }
        long itemNum = CommonUtils.countPerValue(baseValue, totalAdd);// 获取百分比计算后的值
        RewardItem rewardItem = new RewardItem(ItemId.DATING_EXP, itemNum, userSecretary);
        return  rewardItem;
    }


    // 随机干员或是秘书
    public static int getRandomPartnerId(JsonArray jsonArray) {
        int random = Tool.getRandom(0, jsonArray.size() - 1);
        int reslut = Integer.parseInt(jsonArray.getString(random));
        return reslut;
    }

    /**
     * 升级触发一次约会次数更新
     * @param oldLevel
     * @param level
     * @param userId
     */
    public static void levelUpToUpdateUserDating(int oldLevel, int level, long userId) {
        UserExp oldUserExp = GameDataManager.getUserExp(oldLevel);
        UserExp userExp = GameDataManager.getUserExp(level);
        if (oldUserExp == null || userExp == null){
            return;
        }
        UserDating userDating = getUserDating(userId);
        if (userDating.getStrength() < userExp.getBeautyNum()){
            userDating.addStrength(1);
            if (userDating.getStrength() < userExp.getBeautyNum()){
                userDating.putRecoverTime(TimeUtils.getCurTime());
            }
            userDating.update();
        }
    }

    // 约会的红点提示
    public static boolean checkRedPointDating(CSGameSystemRedPointResponse.Builder builder, UserInfo userInfo){
        CsGameSystem.RedPoint_Dating.Builder redPointDating = CsGameSystem.RedPoint_Dating.newBuilder();
        UserDating userDating = getUserDating(userInfo.getId());
        if (userDating.getStrength() >= userDating.takeMaxStrength(userInfo)) {
            redPointDating.setEnergy(true);
        }
        long userItemNum = BagManager.getUserItemNum(userInfo, ItemId.DATING_DINNER);
        if (userItemNum > 0) {
            redPointDating.setItem(true);
        }

        if (redPointDating.getEnergy() || redPointDating.getItem()) {
            builder.setDating(redPointDating);
            return true;
        } else {
            return false;
        }
    }

    // 从缓存里取秘书数据
    public static UserSecretary getUserSecr(long userId, int secrId, ConcurrentHashMap<Integer, UserSecretary> userSecretaryList) {
        if (userSecretaryList.containsKey(secrId)) {
            return userSecretaryList.get(secrId);
        } else {
            UserSecretary userSecretary = SecretaryManager.getUserSecretary(userId, secrId);
            userSecretaryList.put(secrId, userSecretary);// 缓存下来避免重复取值
            return userSecretary;
        }
    }

    // 从缓存里取干员数据
    public static UserPartner getUserPartner(long userId, int partnerId, ConcurrentHashMap<Integer, UserPartner> userpartnerList) {
        if (userpartnerList.containsKey(partnerId)) {
            return userpartnerList.get(partnerId);
        } else {
            UserPartner userPartner = PartnerManager.getUserPartner(userId, partnerId);
            userpartnerList.put(partnerId, userPartner);// 缓存下来避免重复取值
            return userPartner;
        }
    }

    // 处理约会的逻辑
    public static void doDating(CSGameDatingDatingResponse.Builder response, UserInfo userInfo, UserChildInfo userChildInfo, UserDating userDating, List<UserChildCls> userChildClsList, JsonArray partnerJsonArray, JsonArray secretaryJsonArray, int index, ConcurrentHashMap<Integer, UserPartner> userPartnerList, ConcurrentHashMap<Integer, UserSecretary> userSecretaryList) {
        PBUserData.Builder pbUserData = response.getUserBuilder();
        long userId = userInfo.getId();
        int partnerId = getRandomPartnerId(partnerJsonArray);// 随机到的干员id
        int secretaryId = getRandomPartnerId(secretaryJsonArray);// 随机到的秘书id
        response.addPartnerIdList(partnerId);
        response.addSecretaryIdList(secretaryId);

        //约会积分奖励，跟成功失败无关
        UserSecretary userSecretary = getUserSecr(userId, secretaryId, userSecretaryList);
        RewardItem rewardItem = DatingManager.takeRewardItemNum(userId, userSecretary, DATING_DATING_TYPE_FREE);
        RewardManager.addReward(userInfo, rewardItem, pbUserData, LogType.DATING_DATING, userSecretary.getSecretaryId());

        UserChildCls userChildCls = takeDatingUserChildCls(userChildClsList);
        if (userChildCls != null) {// userChildCls null 表示教室已满 必定不生小孩
            UserPartner userPartner = getUserPartner(userId, partnerId, userPartnerList);
            if (checkDatingSucc(userDating, userChildCls) || (index == 0 && DatingManager.checkFirstDating(userChildInfo))) {// 第一次约会必定生小孩
                response.setResult(1);//
                boolean isTwins = Tool.checkRandom(AllParam.CHILD_IS_TWINS / Constant.HUNDRED);//随机子嗣是否双胞胎
                ChildManager.createChild(pbUserData, userChildCls, userPartner, userSecretary, isTwins);
                userChildCls.update();
                ProtoDataUtils.updatePBUserData(pbUserData, userChildCls);
            }
        }
        userDating.addDateNum(1);// 计算概率用的
        userChildInfo.putIsHaveDating(1);// 表示已经约会过了
    }

    // 判断概率,是否约会成功,有生小孩
    public static boolean checkDatingSucc(UserDating userDating, UserChildCls userChildCls){
        if (userChildCls == null) {
            return false;// userChildCls null 表示教室已满 必定不生小孩
        }
        int num = userDating.getDateNum() + 1;// 已约会次数 + 1== 本次是第几次约会
        int aa = AllParam.DATING_DATING_SUCCESS_RATE.length;//{1000, 1000, 10000, 1000, 1500, 3000}
        int cc = num % aa;// 取余数  第9次, cc= 3
        if (cc == 0) {
            cc = aa;
        }
        int rate = AllParam.DATING_DATING_SUCCESS_RATE[cc - 1];// 第9次,概率10000
        boolean random = Tool.checkRandom(rate/100);
        return random;
    }

    public static UserChildCls takeDatingUserChildCls(List<UserChildCls> userChildClsList) {
        for (UserChildCls userChildCls : userChildClsList) {
            if (userChildCls.getIsStudy() == 0) {
                return userChildCls;
            }
        }
        return null;
    }

    //  判断该玩家是否第一次约会，首次约会必定生小孩
    public static boolean checkFirstDating(UserChildInfo userChildInfo) {
        if (userChildInfo.getIsHaveDating() == 0) {
            return true;
        } else {
            return false;
        }
    }
}
